/*!
 * @file skyboxMenager.cpp
 * @brief Ciało skyboxMenager.hh
 */

#include "modes/world/skybox/skyboxMenager.hh"
using namespace std;

/*--------------------------------------------------------------------------*/

skyboxMenager::skyboxMenager() {

	this->initSky();

}

/*--------------------------------------------------------------------------*/

void skyboxMenager::initSky() {
	this->sky_shader = new shader("skyShader");
	this->sky_shader->addShader("pawirr/shaders/skybox.v", ST_V);
	this->sky_shader->addShader("pawirr/shaders/skybox.f", ST_F);

	point3f *vert = new point3f[6144];
	point3f *texc = new point3f[6144];

	int counter = 0;

	float flX, flZ;
	for (float x = -M_PI; x < M_PI; x += M_PI / 32) {
		for (float y = 0; y < M_PI / 2; y += M_PI / 32) {

			for (int nTri = 0; nTri < 6; nTri++) {

				flX = x + ((nTri == 1 || nTri == 2 || nTri == 5) ? M_PI / 32
						: 0);
				flZ = y + ((nTri == 1 || nTri == 4 || nTri == 5) ? M_PI / 32
						: 0);

				vert[counter].x = cos(flZ) * cos(flX);
				vert[counter].y = sin(flZ);// * 0.5f - 0.125f;
				vert[counter].z = cos(flZ) * sin(flX);

				texc[counter].x = (cos(flZ) * cos(flX) / 2);
				texc[counter].y = (cos(flZ) * sin(flX) / 2);
				texc[counter].z = 1;
				counter++;
			}

		}
	}

	glGenVertexArrays(1, &this->sky_vao);
	glBindVertexArray(this->sky_vao);
	glGenBuffers(2, this->sky_vbo);

	glBindBufferARB(GL_ARRAY_BUFFER, this->sky_vbo[0]);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, 6144 * sizeof(point3f), vert,
			GL_STATIC_DRAW_ARB);

	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(point3f), NULL);
	delete[] vert;
	this->sky_shader->addAttrib("attPos", 0);

	/*-----------*/
	glBindBufferARB(GL_ARRAY_BUFFER, this->sky_vbo[1]);
	glBufferDataARB(GL_ARRAY_BUFFER_ARB, 6144 * sizeof(point3f), texc,
			GL_STATIC_DRAW_ARB);

	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(point3f), NULL);
	delete[] texc;
	this->sky_shader->addAttrib("attTex", 1);

	pawirr::graphic->_env->addEnvUniforms(this->sky_shader);

	this->sky_shader->linkProgram();
	glBindVertexArray(0);

	this->cloud1 = new texture("pawirr/textures/clouds/cloud1.png");
	this->sky_shader->addTexture("tex_cloud1", this->cloud1);

	this->godraysTex = new texture(pawirr::graphic->resX/4,
			pawirr::graphic->resY/4);
}

/*--------------------------------------------------------------------------*/

point3f skyboxMenager::getSunWindowCoords(){

	point3f camPos = pawirr::graphic->_env->cameraPos;
	point3f lightDir = pawirr::graphic->_env->lightDiffuseSource * pawirr::graphic->_env->visualRange * 0.8f;

	point3f finalPos = camPos + lightDir;

	point3f result;

	GLdouble modelview[16], projection[16];
	GLint viewport[4];

	glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
	glGetDoublev(GL_PROJECTION_MATRIX, projection);
	glGetIntegerv(GL_VIEWPORT, viewport);

	double x, y, z;

	gluProject(finalPos.x, finalPos.y, finalPos.z, modelview, projection, viewport, &x, &y, &z);

	return point3f(x,y,z);
}

/*--------------------------------------------------------------------------*/

texture *skyboxMenager::getGodraysTexture(){
	return this->godraysTex;
}

/*--------------------------------------------------------------------------*/

void skyboxMenager::draw(skybox_drawMode dm) {

	if (dm == skybox_dm_skybox || dm == skybox_dm_all) {
		glPushMatrix();
		glTranslatef(pawirr::graphic->_env->cameraPos.x, pawirr::graphic->_env->cameraPos.y,
				pawirr::graphic->_env->cameraPos.z);

		glScalef(pawirr::graphic->_env->visualRange,
				pawirr::graphic->_env->visualRange,
				pawirr::graphic->_env->visualRange);

		this->sky_shader->bind();

		glBindVertexArray(this->sky_vao);
		glDrawArrays(GL_TRIANGLES, 0, 6144);
		glBindVertexArray(0);

		this->sky_shader->unbind();
		glPopMatrix();
	}

	if (dm == skybox_dm_sun || dm == skybox_dm_all) {
		glPushMatrix();
		glTranslatef(pawirr::graphic->_env->cameraPos.x, pawirr::graphic->_env->cameraPos.y,
				pawirr::graphic->_env->cameraPos.z);

		glScalef(pawirr::graphic->_env->visualRange * 0.8f,
				pawirr::graphic->_env->visualRange * 0.8f,
				pawirr::graphic->_env->visualRange * 0.8f);

		glPointSize(1000.0f);
		glEnable(GL_POINT_SMOOTH);

		pawirr::graphic->_env->stopLights();
		glBegin(GL_POINTS);

		//if(dm == skybox_dm_sun) //maluję samo słońce - godrays
		//	glColor4f(1.0, 1.0, 1.0, 0.05);
		//else //maluję standard
			glColor4f(1.0, 1.0, 1.0, 1.0);


		glVertex3f(pawirr::graphic->_env->lightDiffuseSource.x,
				pawirr::graphic->_env->lightDiffuseSource.y,
				pawirr::graphic->_env->lightDiffuseSource.y);
		glEnd();
		pawirr::graphic->_env->startLights();
		glPointSize(1.0f);
		glDisable(GL_POINT_SMOOTH);
		glPopMatrix();
	}

}

/*--------------------------------------------------------------------------*/
